package htmlToWord;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.*;

/**
 * TODO 描述: Html解析导入Excel完整版
 *
 * @author yanzhengwu
 * @create 2020-12-25 13:56
 */

public class HtmlToWord {




    public static void main(String[] args) throws IOException {
        String htmlStr = "<p style=\"margin-right:32px;text-indent:2px\"><span style=\"font-family: 宋体, SimSun;\"><span style=\"font-size: 14px;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><span\n" +
                "            style=\"font-size: 20px;\">单元工程施工质量报验单</span></strong></span></p>\n" +
                "    <p style=\"margin-right:32px;text-indent:2px\"><span style=\"font-family: 宋体, SimSun;\"><span\n" +
                "            style=\"text-align: center; line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（</span><span\n" +
                "            style=\"text-align: center; line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{公司简称}</span><span\n" +
                "            style=\"text-align: center; line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;[</span><span\n" +
                "            style=\"text-align: center; line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{年份}</span><span\n" +
                "            style=\"text-align: center; line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">]质报</span><span\n" +
                "            style=\"text-align: center; line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{子单元工程序号}</span><span\n" +
                "            style=\"text-align: center; line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">号）</span></span>\n" +
                "    </p>\n" +
                "    <p style=\"text-indent:12px\"><span style=\"font-family: 宋体, SimSun;\"><span\n" +
                "            style=\"font-size: 12px; font-family: 宋体, SimSun;\">合同名称：</span><span\n" +
                "            style=\"color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{合同名称}</span><span\n" +
                "            style=\"font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;合同编号：</span><span\n" +
                "            style=\"color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{合同编号}</span></span></p>\n" +
                "    <table border=\"1px solid #000000\" cellspacing=\"0\" width=\"634\">\n" +
                "        <tbody>\n" +
                "        <tr class=\"firstRow\">\n" +
                "            <td width=\"634\" valign=\"top\" colspan=\"2\"\n" +
                "                style=\"padding: 0px 7px; border-width: 1px; border-color: windowtext; word-break: break-all;\"><p\n" +
                "                    style=\";line-height:150%\"><span style=\"font-family: 宋体, SimSun;\"><span\n" +
                "                    style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">致：</span><span\n" +
                "                    style=\"line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{监理单位名称}</span></span>\n" +
                "            </p>\n" +
                "                <p style=\"margin-left:8px;text-indent:18px;line-height:150%\"><span\n" +
                "                        style=\"font-family: 宋体, SimSun;\"><span\n" +
                "                        style=\"line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{子单元工程部位}</span><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">单元工程 (</span><span\n" +
                "                        style=\"line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{子单元工程序号}</span><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">）□ 工序/☑ 单元工程已按合同要求完成施工经自检合格，报请贵方核验。</span></span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:24px;line-height:23px\"><span style=\"font-family: 宋体, SimSun;\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">附件： </span><span\n" +
                "                        style=\"line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{附件}</span><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span></span></p>\n" +
                "                <p style=\"text-indent:108px;line-height:23px\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span></p>\n" +
                "                <p style=\"text-indent:360px\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:360px\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:360px\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:360px\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:360px\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:360px\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:360px\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:324px;line-height:150%\"><span style=\"font-family: 宋体, SimSun;\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">承 包 人：</span><span\n" +
                "                        style=\"line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{施工单位名称}</span></span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:384px;line-height:150%\"><span style=\"font-family: 宋体, SimSun;\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span><span\n" +
                "                        style=\"font-size: 12px; font-family: 宋体, SimSun;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 项目经理：</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 日 &nbsp;&nbsp;&nbsp;期： &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;年 &nbsp;&nbsp;&nbsp;月 &nbsp;&nbsp;日</span>\n" +
                "                </p></td>\n" +
                "        </tr>\n" +
                "        <tr style=\"height:511px\">\n" +
                "            <td width=\"60\" valign=\"center\"\n" +
                "                style=\"padding: 0px 7px; border-left-width: 1px; border-left-color: windowtext; border-right-width: 1px; border-right-color: windowtext; border-top: none; border-bottom-width: 1px; border-bottom-color: windowtext; word-break: break-all;\">\n" +
                "                <p style=\"margin-top:21px;text-align:center\">\n" +
                "                    <span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">监理机构意见</span></p></td>\n" +
                "            <td width=\"574\" valign=\"top\"\n" +
                "                style=\"padding: 0px 7px; border-left: none; border-right-width: 1px; border-right-color: windowtext; border-top-width: 1px; border-top-color: windowtext; border-bottom-width: 1px; border-bottom-color: windowtext; word-break: break-all;\">\n" +
                "                <p><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span></p>\n" +
                "                <p><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">复核结果：</span></p>\n" +
                "                <p style=\"text-indent:108px;line-height:150%\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">□同意进入下一工序 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;□不同意进入下一工序</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;□同意进入下一单元工程&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;□不同意进入下一单元工程</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"line-height:150%\"><span style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span>\n" +
                "                </p>\n" +
                "                <p style=\"text-indent:264px\"><span style=\"font-family: 宋体, SimSun;\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">监理机构：</span><span\n" +
                "                        style=\"line-height: 150%; color: #FF0000; font-size: 12px; font-family: 宋体, SimSun;\">{监理单位名称}</span><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span></span></p>\n" +
                "                <p style=\"margin-left:281px;line-height:150%\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">&nbsp;</span></p>\n" +
                "                <p style=\"text-indent:300px;line-height:150%\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">监理工程师：</span></p>\n" +
                "                <p style=\"margin-top:21px;text-indent:300px;line-height:150%\"><span\n" +
                "                        style=\"line-height: 150%; font-size: 12px; font-family: 宋体, SimSun;\">日 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;期： &nbsp;&nbsp;&nbsp;&nbsp;年 &nbsp;&nbsp;&nbsp;月 &nbsp;&nbsp;日</span>\n" +
                "                </p></td>\n" +
                "        </tr>\n" +
                "        <tr>\n" +
                "            <td valign=\"top\" colspan=\"1\" rowspan=\"1\"\n" +
                "                style=\"border-left-color: windowtext; border-left-width: 1px; border-top-color: windowtext; border-top-width: 1px; word-break: break-all;\">\n" +
                "                <br/></td>\n" +
                "            <td valign=\"top\" colspan=\"1\" rowspan=\"1\"\n" +
                "                style=\"border-left-color: windowtext; border-left-width: 1px; border-top-color: windowtext; border-top-width: 1px; word-break: break-all;\">\n" +
                "                <br/></td>\n" +
                "        </tr>\n" +
                "        </tbody>\n" +
                "    </table>\n" +
                "    <p style=\"text-indent:11px\"><span style=\"font-size: 11px; font-family: 宋体, SimSun;\">说明：本表一式 &nbsp;份，由承包人填写，监理机构审签后，承包人___份、监理机构___份、发包人___份、设 代机构___份。</span>\n" +
                "    </p>\n" +
                "    <p><br/></p>";
        Map<String, Map<String, Object>> data = new HashMap<>();
        HtmlToWord toWord = new HtmlToWord(data, htmlStr);

        //Document doc = Jsoup.parse(htmlStr);
        CustomXWPFDocument xwpfDocument = toWord.htmlToWord();
        Long date = System.currentTimeMillis();
        String path = "F:/htmlToWord/" + date + "text.docx";
        OutputStream outputStream = new FileOutputStream(path);
        System.out.println("导出完成:" + path);
        xwpfDocument.write(outputStream);
        outputStream.close();

    }

    /**
     * 必须传入数据否则无法生成
     *
     * @param data
     */
    public HtmlToWord(Map<String, Map<String, Object>> data, String htmlStr) {
        this.data = data;
        this.htmlStr = htmlStr;
    }

    /**
     * 需要填充的数据
     */
    private Map<String, Map<String, Object>> data;
    /**
     * html字符串
     */
    private String htmlStr;

    /**
     * TODO html表格转word程序入口
     *
     * @return
     */
    public CustomXWPFDocument htmlToWord() throws IOException {
        File input = new File("D:/Java/IDEA-Project/htmlToWord/src/main/resources/报告单.html");
        Document doc = Jsoup.parse(input, "UTF-8", "https://www.jb51.net/");
        //Document doc = Jsoup.parse(htmlStr);
        //储存合并后的区域以便合并单元格
        List<CrossRangeCellMeta> crossRowEleMetaLs = new ArrayList<>();
        CustomXWPFDocument xWPFDocument = new CustomXWPFDocument();

        Elements elements = doc.select("body");
        if (null != elements && elements.size() > 0) {
            if (null != elements.get(0)) {
                setData(xWPFDocument, elements.get(0).children());
            }

        }
        System.out.println("合并单元格区域坐标如下：");
        //合并单元格需要重新写样式
        /*for (CrossRangeCellMeta crcm : crossRowEleMetaLs) {
            sheet.addMergedRegion(new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()));
            System.out.println("开始行" + crcm.getFirstRow() + "--结束行" + crcm.getLastRow() + "--开始列" + crcm.getFirstCol() + "--结束列" + crcm.getLastCol());
            for (int i = crcm.getFirstRow(); i <= crcm.getLastRow(); i++) {
                for (int j = crcm.getFirstCol(); j <= crcm.getLastCol(); j++) {
                    sheet.getRow(i).getCell(j).setCellStyle(crcm.getCellStyle());
                }
            }
        }*/

        return xWPFDocument;
    }

    //设置数据
    private void setData(CustomXWPFDocument xWPFDocument, Elements elements) {
        for (int i = 0; i < elements.size(); i++) {
            Element element = elements.get(i);
            if (i == 0) {
                if ("p".equals(element.tagName())) {
                    setTitleValueAndStyle(xWPFDocument, null, element);
                    continue;
                }
            }
            if ("p".equals(element.tagName())) {
                XWPFParagraph xwpfParagraph = xWPFDocument.createParagraph();
                readPTag(xwpfParagraph, element);

            }
            if ("table".equals(element.tagName())) {
                XWPFTable table = xWPFDocument.createTable();
                //List<XWPFTableRow> rows= table.getRows();
                int rowIndex = 0;//开始行
                int j = 0;//第一次去默认创建的行
                if (elements != null) {
                    List<Element> trLs = elements.select("tr");
                    for (Element trEle : trLs) {
                        XWPFTableRow row;
                        if (j == 0) {
                            row = table.getRow(0);
                        } else {
                            row = table.createRow();
                            while (row.getTableCells().size()>1){
                                row.removeCell(0);
                            }
                        }
                        j++;
                        //XWPFTableRow row=table.createRow();
                        String height = element.attr("height");
                        /*if (null != height && !"".equals(height) && Integer.parseInt(height) > 0) {
                            CTTbl ttbl = table.getCTTbl();
                            CTTblGrid tblGrid = ttbl.addNewTblGrid();
                            CTTblGridCol gridCol = tblGrid.addNewGridCol();
                            gridCol.setW(BigInteger.valueOf(Integer.parseInt(height)));*/
                        //设置行高参数
                        //setRowHeight(row, Integer.parseInt(null == height || height.equals("") ? "6000" : height));
                        //}
                        List<Element> tdLs = trEle.select("td");
                        readTableTag(tdLs, table, row, rowIndex);
                        rowIndex++;
                    }
                }
                if (null != table) {
                    //合并单元格
                    mergeCell(table);
                }
            }

        }

    }

    /**
     * 跨列合并
     *
     * @param table
     * @param row       所合并的行
     * @param startCell 起始列
     * @param endCell   终止列
     * @Description
     */
    public void mergeCellsHorizontal(XWPFTable table, int row, int startCell, int endCell) {
        for (int cellIndex = startCell; cellIndex <= endCell; cellIndex++) {
            System.out.println("第:" + row + "行;第:" + startCell + "列");
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if (null != cell) {
                if (cellIndex == endCell) {
                    CTTc ctTc = cell.getCTTc();
                    ctTc.addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
                } else {
                    cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
                }
            }
        }
    }

    /**
     * 合并表格
     *
     * @param table
     */
    private void mergeCell(XWPFTable table) {
        for (CrossRangeCellMeta crcm : crossRowEleMetaLs) {
            List<XWPFTableRow> rows = table.getRows();
            //System.out.println( "开始行"+crcm.getFirstRow()+"开始列"+crcm.getFirstCol()+"结束列"+crcm.getLastCol());
            //mergeCellsHorizontal(table, crcm.getFirstRow(), crcm.getFirstCol(), crcm.getLastCol());

            /*for (int i = 0; i < rows.size(); i++) {
                XWPFTableRow row = rows.get(i);
                List<XWPFTableCell> cells = row.getTableCells();
                for (int j = 0; j < cells.size(); j++) {
                    String index = "第" + i + "行/第" + j + "列";
                    XWPFTableCell cell = cells.get(j);
                    CTTc ctTc = cell.getCTTc();
                    CTTcPr ctTcPr = ctTc.getTcPr();
                    if (null != ctTcPr) {
                        System.out.println(index + "  /有ctTcPr");
                        //STOnOff.Enum e = ctTcPr.getTcFitText().getVal();
                        //System.out.println("Enum==" + e);
                    } else {
                        System.out.println(index + "  /不存在ctTcPr");
                    }
                }*/

            CTVMerge startVmerge = CTVMerge.Factory.newInstance();
            startVmerge.setVal(STMerge.RESTART);
            CTVMerge endVmerge = CTVMerge.Factory.newInstance();
            endVmerge.setVal(STMerge.CONTINUE);
            /*for (int i = crcm.getFirstRow(); i <= crcm.getLastRow(); i++) {
                for (int j = crcm.getFirstCol(); j <= crcm.getLastCol(); j++) {
                    XWPFTableCell startCell = rows.get(crcm.getFirstRow()).getCell(crcm.getFirstCol());
                    startCell.getCTTc().getTcPr().setVMerge(startVmerge);

                    XWPFTableCell endCell = rows.get(crcm.getFirstRow()).getCell(crcm.getFirstCol());
                    endCell.getCTTc().getTcPr().setVMerge(endVmerge);
                }
            }*/
            //System.out.println("crcm:" + crcm);
                /*for (int i = crcm.getFirstRow(); i <= crcm.getLastRow(); i++) {
                    for (int j = crcm.getFirstCol(); j <= crcm.getLastCol(); j++) {
                        System.out.println("开始行："+crcm.getFirstRow()+"---开始列："+crcm.getFirstCol());

                    }
                }*/
            //}
        }
    }


    private void setTableData(XWPFTableCell cell, Element element) {
        String widthAttr = element.attr("width");
        if (!StringUtils.isEmpty(widthAttr) && Integer.parseInt(widthAttr) > 0) {
            Integer width = Integer.parseInt(widthAttr);
            //设置列宽
            setCellWith(cell, width);
        }
        cell.addParagraph().insertNewRun(0).setText(element.ownText());
        if (null != element && element.children().size() > 0) {
            Elements elements = element.children();
            for (int i = 0; i < elements.size(); i++) {
                Element el = elements.get(i);
                if ("p".equals(el.tagName())) {
                    XWPFParagraph xwpfParagraph = cell.addParagraph();
                    readPTag(xwpfParagraph, el);
                }

            }
        }

    }


    //读取<p>标签
    private void readPTag(XWPFParagraph xwpfParagraph, Element element) {

        if (!StringUtils.isEmpty(element.attr("data-source"))) {
            if (!StringUtils.isEmpty(element.attr("data-column"))) {
                String dataSourceKey = element.attr("data-source");
                String dataColumnKey = element.attr("data-column");
                Object obj = data.get(dataSourceKey).get(dataColumnKey);
                if (!StringUtils.isEmpty(obj)) {
                    XWPFRun run = xwpfParagraph.createRun();
                    run.setText(obj.toString());
                    setRunStyle(run, element);
                }
            }
        }
        XWPFRun run = xwpfParagraph.createRun();
        run.setText(element.ownText());
        setRunStyle(run, element);

        //如果有子节点标签则继续读取
        if (null != element.children() && element.children().size() > 0) {
            for (Element el : element.children()) {
                readPTag(xwpfParagraph, el);
            }
        }

    }

    List<CrossRangeCellMeta> crossRowEleMetaLs = new ArrayList<>();

    //读取<Table>标签
    private void readTableTag(List<Element> tdLs, XWPFTable table, XWPFTableRow row, int rowIndex) {

        System.out.println("rowIndex:"+rowIndex);
        //if (rowIndex==3) return;
        //开始列数
        int cellIndex = 0;
        for (int eleIndex = 0; eleIndex < tdLs.size(); cellIndex++, eleIndex++) {
            Element tdEle = tdLs.get(eleIndex);
            String tdWidth = tdEle.attr("width");

            XWPFTableCell cell = null;
            if (row.getTableCells().size() == 1) {
                cell = row.getCell(0);
                Integer width = Integer.parseInt(tdWidth == null || tdWidth.equals("") ? "4000" : tdWidth);
                //设置列宽
                setCellWith(cell, width);
            } else {
                System.out.println("创建第" + rowIndex + "行；第" + cellIndex + "列");
                cell = row.addNewTableCell();
                Integer width = Integer.parseInt(tdWidth == null || tdWidth.equals("") ? "400" : tdWidth);
                //设置列宽
                setCellWith(cell, width);
            }

            //设置表格数据
            if (null != cell) {
                setTableData(cell, tdEle);
            }

            int rowSpan = NumberUtils.toInt(tdEle.attr("rowspan"), 1);
            int colSpan = NumberUtils.toInt(tdEle.attr("colspan"), 1);
            if (rowSpan > 1 || colSpan > 1) { // 存在跨行或跨列
                //System.out.println("开始行：" + rowIndex + "开始列：" + i + "结束行：" + (rowSpan-1) + "结束列:" + (colSpan-1));
                crossRowEleMetaLs.add(new CrossRangeCellMeta(rowIndex, cellIndex, rowSpan, colSpan));
            }
            if (colSpan > 1) {// 当前行跨列处理（补单元格）
                for (int j = 1; j < colSpan; j++) {
                    cellIndex++;
                    XWPFTableCell newCell = row.addNewTableCell();
                    String widthAttr = tdEle.attr("width");
                    Integer width = Integer.parseInt(widthAttr == null || widthAttr.equals("") ? "400" : widthAttr);
                    //设置列宽
                    setCellWith(newCell, width);
                }
            }
        }

    }

    private void setRowHeight(XWPFTableRow row, Integer height) {
        //设置网格属性
        CTTrPr trPr = row.getCtRow().addNewTrPr();
        trPr.addNewGridAfter();
        trPr.addNewGridBefore();
        CTHeight h = trPr.addNewTrHeight();
        h.setVal(BigInteger.valueOf(height));

    }

    private void setCellWith(XWPFTableCell cell, Integer width) {
        //设置列宽
        CTTcPr cPr1 = cell.getCTTc().addNewTcPr();
        CTTblWidth w = cPr1.addNewTcW();
        w.setW(BigInteger.valueOf(width));
        CTTcPr ctTcPr = cell.getCTTc().getTcPr();
        //System.out.println(ctTcPr);
    }

    /**
     * 设置Run字体样式
     *
     * @param run
     * @param element
     */
    private void setRunStyle(XWPFRun run, Element element) {
        Attributes attributes = element.attributes();
        if (null != attributes && attributes.size() > 0) {
            readAttributes(run, attributes);
        }
        readTagStyle(run, element);

    }

    /**
     * 读取标签样式并设置run样式
     *
     * @param run
     * @param element
     */
    private void readTagStyle(XWPFRun run, Element element) {

        switch (element.tagName()) {
            case "i":
                run.setItalic(true);
                //System.out.println("获取到字体[倾斜]");
                break;
            case "strong":
                run.setBold(true);
                //System.out.println("获取到字体[加粗]");
                break;
            case "u":
                run.setUnderline(UnderlinePatterns.SINGLE);
                //System.out.println("获取到字体[下划线]");
                break;
            case "s":
                run.setStrikeThrough(true);
                //System.out.println("获取到字体[删除线]");
                break;

            default:

        }

    }

    /**
     * 读取标签属性
     *
     * @param run
     * @param attributes
     */
    public void readAttributes(XWPFRun run, Attributes attributes) {
        List<String> attrValues = new ArrayList<>();
        for (Iterator<Attribute> it = attributes.iterator(); it.hasNext(); ) {
            Attribute attribute = it.next();
            attrValues.add(attribute.getValue());
        }
        //System.out.println(attrValues);
        //System.out.println("---------------------------");


        Map<String, String> attrs = new HashMap<>();
        for (String val : attrValues) {
            String[] attr = val.split(";");
            if (null != attr && attr.length > 0) {
                for (String val2 : attr) {
                    String[] kvs = val2.split(":");
                    if (null != kvs && kvs.length > 1) {
                        attrs.put(kvs[0].trim(), kvs[1].replace(" ", ""));
                    }
                }
            }
        }
        runSetStyle(attrs, run);

    }

    /**
     * 设置run空间 匹配到的字体样式
     *
     * @param attrs
     * @param run
     */
    public void runSetStyle(Map<String, String> attrs, XWPFRun run) {
        for (String key : attrs.keySet()) {
            switch (key) {
                case "font-family":
                    String family = attrs.get(key);
                    String[] f = family.split(",");
                    if (!StringUtils.isEmpty(f[0])) {
                        run.setFontFamily(f[0]);
                    }
                    //System.out.println("匹配到字体类型：" + attrs.get(key));
                    break;
                case "font-size":
                    String size = attrs.get(key).replace("px", "");
                    Integer fontSize = Integer.parseInt(size);
                    if (fontSize > 0) {
                        run.setFontSize(fontSize);
                    }
                    //System.out.println("匹配到字体大小：" + attrs.get(key));
                    break;
                case "text-align":
                    //System.out.println("匹配到字体浮动：" + attrs.get(key));
                    break;
                case "color":
                    String colorRGB = attrs.get(key);
                    //没有#号说明不是RGB颜色格式
                    if (colorRGB.contains("#")) {
                        java.awt.Color color = java.awt.Color.decode(colorRGB);
                        if (null != color) {
                            run.setColor(attrs.get(key).replace("#", ""));
                        }
                    }
                    //System.out.println("匹配到字体颜色：" + attrs.get(key));
                    break;
                default:
            }
        }
    }

    /**
     * 设置标题值填充和样式填充
     *
     * @param xWPFDocument
     * @param xwpfParagraph
     * @param element
     */
    private void setTitleValueAndStyle(CustomXWPFDocument xWPFDocument, XWPFParagraph xwpfParagraph, Element element) {
        if (null == xwpfParagraph) {
            xwpfParagraph = xWPFDocument.createParagraph();
        }
        if (!StringUtils.isEmpty(element.attr("data-source"))) {
            if (!StringUtils.isEmpty(element.attr("data-column"))) {
                String dataSourceKey = element.attr("data-source");
                String dataColumnKey = element.attr("data-column");
                if (data.containsKey(dataSourceKey) && data.get(dataSourceKey).containsKey(dataColumnKey)) {
                    Object obj = data.get(dataSourceKey).get(dataColumnKey);
                    if (!StringUtils.isEmpty(obj)) {
                        XWPFRun run2 = xwpfParagraph.createRun();
                        run2.setText(obj.toString());
                        run2.setFontFamily("宋体");
                        run2.setBold(true);
                        run2.setFontSize(14);
                        run2.setColor("FF0000");//红色
                    }
                }
            }
        }
        String ownText = element.ownText();
        if (!StringUtils.isEmpty(ownText)) {
            ownText = deleteBlank(ownText);
            if (!StringUtils.isEmpty(ownText)) {
                XWPFRun run = xwpfParagraph.createRun();
                run.setText(ownText);
                run.setFontFamily("宋体");
                run.setBold(true);
                run.setFontSize(14);

            }

        }
        //如果有子节点标签则继续读取
        if (null != element.children() && element.children().size() > 0) {
            for (Element el : element.children()) {
                setTitleValueAndStyle(xWPFDocument, xwpfParagraph, el);
            }
        }

        // 文档设置段落居中
        xwpfParagraph.setAlignment(ParagraphAlignment.CENTER);

    }

    /**
     * 删除字符串中单引号或双引号所占的空白区域
     *
     * @param text
     * @return
     */
    private String deleteBlank(String text) {
        if (null == text) {
            return "";
        }
        text = text.replace((Jsoup.parse("&nbsp;").text()), "");
        return text;
    }


    /**
     * 获得因rowSpan占据的单元格
     *
     * @param rowIndex          行号
     * @param colIndex          列号
     * @param crossRowEleMetaLs 跨行列元数据
     * @return 当前行在某列需要占据单元格
     */
    private static int getCaptureCellSize(int rowIndex, int colIndex, List<CrossRangeCellMeta> crossRowEleMetaLs) {
        int captureCellSize = 0;
        if (null != crossRowEleMetaLs && crossRowEleMetaLs.size() > 0) {
            for (CrossRangeCellMeta crossRangeCellMeta : crossRowEleMetaLs) {
                if (crossRangeCellMeta.getFirstRow() < rowIndex && crossRangeCellMeta.getLastRow() >= rowIndex) {
                    if (crossRangeCellMeta.getFirstCol() <= colIndex && crossRangeCellMeta.getLastCol() >= colIndex) {
                        captureCellSize = crossRangeCellMeta.getLastCol() - colIndex + 1;
                    }
                }
            }
        }
        return captureCellSize;
    }

    /**
     * 合并单元格后的区域坐标和样式
     */
    private class CrossRangeCellMeta {

        private int firstRowIndex;//开始行
        private int firstColIndex;//开始列
        private int rowSpan;// 跨越行数
        private int colSpan;// 跨越列数


        public CrossRangeCellMeta(int firstRowIndex, int firstColIndex, int rowSpan, int colSpan) {
            super();
            this.firstRowIndex = firstRowIndex;
            this.firstColIndex = firstColIndex;
            this.rowSpan = rowSpan;
            this.colSpan = colSpan;
        }

        /**
         * 开始行
         *
         * @return
         */
        int getFirstRow() {
            return firstRowIndex;
        }

        /**
         * 结束行
         *
         * @return
         */
        int getLastRow() {
            return firstRowIndex + rowSpan - 1;
        }

        /**
         * 开始列
         *
         * @return
         */
        int getFirstCol() {
            return firstColIndex;
        }

        /**
         * 结束列
         *
         * @return
         */
        int getLastCol() {
            return firstColIndex + colSpan - 1;
        }

        @Override
        public String toString() {
            return "CrossRangeCellMeta{" +
                    "开始行：=" + firstRowIndex +
                    ",开始列：=" + firstColIndex +
                    ", 结束行：=" + rowSpan +
                    ", 结束列：=" + colSpan +
                    '}';
        }
    }


}
